package com.example.hms.util;

// 导入需要的JWT处理库和Spring框架的组件注解
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
// 导入Objects类用于对象比较
import java.util.Objects;

// 使用@Component注解，表明这是一个Spring组件，可以被自动扫描并注册为Bean
@Component
public class TokenUtil {
    // 定义一个静态字符串作为密钥，用于JWT的签名和验证
    static String TOKENS = "pyxgwt";

    /**
     * 生成JWT Token
     * @param userId 用户ID
     * @param userName 用户名
     * @param roleName 角色名
     * @param time 时间戳
     * @return 生成的JWT字符串
     */
    // 加密方法，用于生成JWT Token
    public static String getToken(String userId,String userName, String roleName, long time) {
        // 创建JWT对象，并添加声明（claims），然后使用HMAC256算法和密钥进行签名
        String token = JWT.create()
                .withClaim("userId", userId) // 添加用户ID声明
                .withClaim("userName",userName) // 添加用户名声明
                .withClaim("roleName", roleName) // 添加角色名声明
                .withClaim("time", time) // 添加时间戳声明
                .sign(Algorithm.HMAC256(TOKENS)); // 使用HMAC256算法和密钥签名
        return token; // 返回生成的Token字符串
    }

    /**
     * 验证并解析JWT Token
     * @param token JWT字符串
     * @return 包含用户ID、角色名和时间戳的Map对象
     */
    // 解密方法，用于验证JWT Token并解析出其中的信息
    public static Map<String, Object> checkToken(String token) {
        // 创建一个HashMap用于存放解析后的数据
        Map<String, Object> map = new HashMap<>();
        // 使用相同的算法和密钥构建一个JWT验证器，并验证Token
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(TOKENS)).build().verify(token);
        // 从验证后的JWT中获取各个声明
        Claim userId = decodedJWT.getClaim("userId");
        Claim roleName = decodedJWT.getClaim("roleName");
        Claim time = decodedJWT.getClaim("time");
        // 将声明中的数据放入Map中
        map.put("userId", userId.asString()); // 将用户ID放入Map
        map.put("roleName", roleName.asString()); // 将角色名放入Map
        map.put("time", time.asLong()); // 将时间戳放入Map
        return map; // 返回包含解析数据的Map
    }
}
